/**
 * Created by PengWei on 2018/7/25.
 */
namespace mengdao {
    /**
     * 依赖执行
     */
    export class InjectorExecute {
        private readonly _dependenceTarget: any;
        private readonly _dependenceParam: string;

        private _parameter: any;

        private readonly _executeQueueList: InjectorExecuteData[];

        /**
         * @param dependenceTarget  依赖类
         * @param {string} dependenceParam 依赖成员变量名
         */
        public constructor(dependenceTarget: any, dependenceParam: string) {
            this._dependenceTarget = dependenceTarget;
            this._dependenceParam = dependenceParam;
            this._parameter = dependenceTarget ? dependenceTarget[dependenceParam] : null;
            this._executeQueueList = [];
        }

        public execute(functionName: string, ...args): boolean {
            if (this._parameter) {
                let executeFunction: Function = this._parameter[functionName]
                if (executeFunction && (typeof executeFunction === "function")) {
                    executeFunction.apply(this._parameter, args);
                    return true;
                }
            } else {
                let data = ObjectPool.getObj(InjectorExecuteData);
                data.functionName = functionName;
                data.params = args;
                this._executeQueueList.push(data);
            }
            return false;
        }

        public validate(): void {
            this._parameter = this._dependenceTarget ? this._dependenceTarget[this._dependenceParam] : null;
            if (this._parameter) {
                while (this._executeQueueList && this._executeQueueList.length) {
                    let data: InjectorExecuteData = this._executeQueueList.shift();
                    this.execute(data.functionName,...data.params);
                    ObjectPool.recycleObj(data);
                }
            }
        }
    }

    export class InjectorExecuteData implements IClear {
        functionName: string;
        params: any[];

        public clear(): void {
            this.functionName = "";
            this.params = null;
        }
    }
}